package com.yanqu.road.server.gameplayer.module.player;

import com.yanqu.road.entity.enums.wechatrank.eWechatRankSwitchStatusType;
import com.yanqu.road.logic.bussiness.player.UserAttributeBussiness;
import com.yanqu.road.logic.pb.AttributePb;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.ePlayerAttrType;
import com.yanqu.road.entity.player.UserAttribute;
import com.yanqu.road.pb.player.AttributeProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.manger.config.InteractiveMgr;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.TimeHelper;
import com.yanqu.road.utils.property.Property;

import java.math.BigInteger;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class AttributeModule extends GeneralModule {

	private Map<ePlayerAttrType, UserAttribute> userAttributeMap;

	private Set<ePlayerAttrType> needSyncAttrTypes;

	public AttributeModule(GamePlayer player) {
		super(player);
		needSyncAttrTypes = new HashSet<>();
	}

	@Override
	public boolean loadData() {
		userAttributeMap = UserAttributeBussiness.getUserAttributeMap(player.getUserId());
		long nowTime = System.currentTimeMillis() / 1000;
		if (!userAttributeMap.containsKey(ePlayerAttrType.LastAutoAddSilverTime)) {
			setAttribute(ePlayerAttrType.LastAutoAddSilverTime, nowTime);
		}
		checkHeartLimit();
		return true;
	}

	@Override
	public boolean afterLoadData() {
		// 初始化元宝
		if (!userAttributeMap.containsKey(ePlayerAttrType.Ingots)) {
			player.getModule(CurrencyModule.class).addCurrency(new Property(GameConfig.GAME_MONEY_INGOTS, BigInteger.valueOf(GameConfig.GAME_YUANBAO_BASE)),
					eLogMoneyType.System, eLogMoneyType.SystemSend);
			player.getModule(CurrencyModule.class).addCurrency(new Property(GameConfig.GAME_MONEY_SILVER, BigInteger.valueOf(GameConfig.GAME_MONEY_BASE)),
					eLogMoneyType.System, eLogMoneyType.SystemSend);
		}
		//初始化幸运值
		if (!userAttributeMap.containsKey(ePlayerAttrType.LuckyValue)){
			setAttribute(ePlayerAttrType.LuckyValue, GameConfig.TURNTABLE_DEFAULT_LUCKY_VALUE);
		}
		return false;
	}

	@Override
	public boolean saveData() {
		for (UserAttribute userAttribute : userAttributeMap.values()) {
			if (userAttribute.isInsertOption()) {
				UserAttributeBussiness.addUserAttribute(userAttribute);
			} else if (userAttribute.isUpdateOption()) {
				UserAttributeBussiness.updateUserAttribute(userAttribute);
			}
		}
		return false;
	}

	@Override
	public void loginSendMsg() {

	}

	/**
	 * 检测祝福极限
	 */
	private void checkHeartLimit() {
		//判断是否达到祝福值下限
		int limitValue = InteractiveMgr.getBeHateLimit();
		if (player.getUserInfo().getHeartCount() < limitValue) {
			player.getUserInfo().setHeartCount(limitValue);
		}
		//上限
		limitValue = InteractiveMgr.getBeLikeLimit(player.getUserId());
		if (player.getUserInfo().getHeartCount() > limitValue) {
			player.getUserInfo().setHeartCount(limitValue);
		}
	}

	public Map<ePlayerAttrType, UserAttribute> getUserAttributeMap() {
		return userAttributeMap;
	}

	public boolean hasAttribute(ePlayerAttrType type) {
		return userAttributeMap.containsKey(type);
	}

	/**
	 * 添加属性值
	 * @param type
	 * @return
	 */
	public long getAttribute(ePlayerAttrType type) {
		if (userAttributeMap.containsKey(type)) {
			return userAttributeMap.get(type).getValue();
		}
		insertAttribute(type);
		return 0L;
	}

	public void setAttribute(ePlayerAttrType type, long newValue) {
		if (userAttributeMap.containsKey(type)) {
			userAttributeMap.get(type).setValue(newValue);
			userAttributeMap.get(type).setLastUpdateTime(System.currentTimeMillis());
		} else {
			addAttribute(type, newValue);
		}
		if (isNeedSyncType(type)) {//需要同步的属性
			syncAttribute(type);
		}
	}

	/**
	 * 设置属性值
	 * @param type
	 * @param addValue
	 */
	public void addAttribute(ePlayerAttrType type, long addValue) {
		addAttributeNoSync(type, addValue);
		syncAttribute(type);
	}

	public void addAttributeNoSync(ePlayerAttrType type, long addValue) {
		if (!userAttributeMap.containsKey(type)) {
			insertAttribute(type);
		}
		UserAttribute attribute = userAttributeMap.get(type);
		attribute.setValue(attribute.getValue() + addValue);
		attribute.setLastUpdateTime(System.currentTimeMillis());
	}

	private UserAttribute insertAttribute(ePlayerAttrType type) {
		UserAttribute attribute = new UserAttribute();
		attribute.setType(type);
		attribute.setUserId(player.getUserId());
		attribute.setValue(0);
		attribute.setLastUpdateTime(System.currentTimeMillis());
		attribute.setInsertOption();
		userAttributeMap.put(type, attribute);
		return attribute;
	}

	/**
	 * 同步属性
	 */
	public void syncAttribute(ePlayerAttrType type) {
		Set<ePlayerAttrType> types = new HashSet<>();
		types.add(type);
		syncAttribute(types);
	}

	/**
	 * 同步属性
	 */
	public void syncAttribute(Set<ePlayerAttrType> types) {
		AttributeProto.AttributeListMsg.Builder listMsg = AttributeProto.AttributeListMsg.newBuilder();
		AttributeProto.AttributeTempMsg.Builder msg;
		for (ePlayerAttrType type : types) {
			if (!isNeedSyncType(type)) {
				continue;
			}
			if (type == ePlayerAttrType.Silver) {
				msg = AttributePb.parseAttributeTempMsg(type, player.getUserInfo().getSilver().toString());
				if(null != msg){
					listMsg.addAttributeList(msg);
				}
			} else if (type == ePlayerAttrType.PatronsExp) {
				msg = AttributePb.parseAttributeTempMsg(type, player.getUserInfo().getPatronsExp().toString());
				if(null != msg){
					listMsg.addAttributeList(msg);
				}
			} else if (type == ePlayerAttrType.Prestige) {
				msg = AttributePb.parseAttributeTempMsg(type, player.getUserInfo().getPrestige().toString());
				if(null != msg){
					listMsg.addAttributeList(msg);
				}
			} else if (type == ePlayerAttrType.VipExp) {
				msg = AttributePb.parseAttributeTempMsg(type, player.getUserInfo().getVipExp() + "");
				if(null != msg){
					listMsg.addAttributeList(msg);
				}
			} else if (type == ePlayerAttrType.HeartCount) {
				msg = AttributePb.parseAttributeTempMsg(type, player.getUserInfo().getHeartCount() + "");
				if(null != msg){
					listMsg.addAttributeList(msg);
				}
			} else {
				msg = AttributePb.parseAttributeTempMsg(type, getAttribute(type) + "");
				if(null != msg){
					listMsg.addAttributeList(msg);
				}
			}
		}
		player.sendPacket(Protocol.U_ATTRIBUTE_SYNC, listMsg);
	}

	public void onDataChange(ePlayerAttrType attrType) {
		synchronized (needSyncAttrTypes) {
			needSyncAttrTypes.add(attrType);
		}
	}

	public void syncDataChange() {
		synchronized (needSyncAttrTypes) {
			if (needSyncAttrTypes.size() > 0) {
				syncAttribute(needSyncAttrTypes);
				needSyncAttrTypes = new HashSet<>();
			}
		}
	}

	public void syncAllAttribute(){
		if(null != userAttributeMap){
			Set<ePlayerAttrType> syncSet = new HashSet<>(userAttributeMap.keySet());
			if(!hasAttribute(ePlayerAttrType.Prestige)){
				syncSet.add(ePlayerAttrType.Prestige);
			}
			if(!hasAttribute(ePlayerAttrType.VipExp)){
				syncSet.add(ePlayerAttrType.VipExp);
			}
			if (!hasAttribute(ePlayerAttrType.HeartCount)) {
				syncSet.add(ePlayerAttrType.HeartCount);
			}
			syncAttribute(syncSet);
		}
	}

	public boolean resetAttr(ePlayerAttrType type, long value) {
		if (userAttributeMap.get(type) != null && !TimeHelper.dateCompare(userAttributeMap.get(type).getLastUpdateTime())) {
			setAttribute(type, value);
			return true;
		}
		return false;
	}

	public static boolean isNeedSyncType(ePlayerAttrType type) {
		if (type.getValue() < ePlayerAttrType.ResetAttrTime.getValue()) {
			return true;
		}
		if (type == ePlayerAttrType.RechargeTotalTimes) {
			return true;
		} else if (type == ePlayerAttrType.TurntableLotteryLuckyTimes) {
			return true;
		}else if (type == ePlayerAttrType.TwinsAutoPassMissionId) {
			return true;
		} else if (type == ePlayerAttrType.SeacraftPirateRiotMaxChapterId) {
			return true;
		} else if (type == ePlayerAttrType.DaoMuJiShaShuLiang){
			return true;
		} else if (type == ePlayerAttrType.FirstRechargeTime) {
			return true;
		} else if (type == ePlayerAttrType.PlatformComponentEvaluateReward){
			return true;
		} else if (type == ePlayerAttrType.CurioMonopolyGuanYinAddition){
			return true;
		}
		return false;
	}

}
